package com.kandinfo.survey.weixin.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authc.credential.PasswordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.kandinfo.base.common.converter.ConverterService;
import com.kandinfo.base.common.dto.ResultDto;
import com.kandinfo.base.common.dto.ResultDtoFactory;
import com.kandinfo.base.common.util.DateUtils;
import com.kandinfo.base.common.util.web.WebUtil;
import com.kandinfo.base.security.SecurityContext;
import com.kandinfo.base.security.constants.RoleConstants;
import com.kandinfo.base.security.domain.Role;
import com.kandinfo.base.security.domain.User;
import com.kandinfo.base.security.domain.UserInfo;
import com.kandinfo.base.security.domain.UserRole;
import com.kandinfo.base.security.dto.UserInfoDto;
import com.kandinfo.base.security.repository.RoleRepository;
import com.kandinfo.base.security.repository.UserInfoRepository;
import com.kandinfo.base.security.repository.UserRepository;
import com.kandinfo.base.security.repository.UserRoleRepository;
import com.kandinfo.base.security.service.UserInfoService;
import com.kandinfo.base.security.service.UserService;
import com.kandinfo.survey.weixin.dto.UserRegistDto;
import com.kandinfo.survey.weixin.service.IWxUserService;

@Service
public class WxUserServiceImpl implements IWxUserService {

//    private static final Logger logger = LoggerFactory.getLogger(WxUserServiceImpl.class);

    @Autowired
    UserRoleRepository userRoleRepository;
    @Autowired
    RoleRepository roleRepository;
    @Autowired
    PasswordService passwordService;
    @Autowired
    UserRepository userRepository;
    @Autowired
    UserInfoService userInfoService;
    @Autowired
    UserInfoRepository userInfoRepository;
    @Autowired
    UserService userService;

    @Override
	public UserInfoDto getUserInfo() {
        User curUser = SecurityContext.getInstance().getCurrentUser();
        UserInfo infoDomain = userInfoService.findByUserId(curUser.getId());
        
        UserInfoDto res = ConverterService.convert(infoDomain, UserInfoDto.class);
        res.setName(curUser.getName());
        res.setBornDate(infoDomain.getBornDate() == null ? null : DateUtils.format(infoDomain.getBornDate(), DateUtils.STRING_PATTERN_SHORT));
		return res;
	}

	@Override
    @Transactional
    public ResultDto doRegist(UserRegistDto userRegistDto) {
        // 查看用户是否存在
        if (userRepository.countByUsername(userRegistDto.getUsername()) > 0) {
            return ResultDtoFactory.toNack("用户已存在!");
        }

        User user = saveUser(userRegistDto);
        
        // 保存用户性质(病人、家属)
        saveUserInfo(userRegistDto, user);
        
        saveRoleUser(user.getId(), userRegistDto.getUserType());

        return ResultDtoFactory.toAck("注册成功!");
    }
	
	@Transactional
	private void saveUserInfo(UserRegistDto userRegistDto, User user) {
	    UserInfo userInfo = userInfoService.findByUserId(user.getId());
	    if (userInfo == null) {
	        userInfo = new UserInfo();
	        userInfo.setCreateBy(user.getId());
	        userInfo.setCreateTs(new Date());
	        userInfo.setUserId(user.getId());
	    }
	    userInfo.setUserType(userRegistDto.getUserType());
	    
	    userInfoService.save(userInfo);
	}
    
    @Transactional
    public User saveUser(UserRegistDto userRegistDto) {
        User toBeSaved = new User();
        // 手机号 同为用户名
        toBeSaved.setUsername(userRegistDto.getUsername());
        toBeSaved.setMobile(userRegistDto.getUsername());
        // to encrypt pwd
        String pwd = passwordService.encryptPassword(getPassword(userRegistDto.getPassword(), userRegistDto.getUsername()));
        toBeSaved.setPassword(pwd);
        // save wx open id
        if (StringUtils.isNotBlank(userRegistDto.getWxOpenId())) {
            toBeSaved.setWxOpenId(userRegistDto.getWxOpenId());
        }
        userRepository.saveAndFlush(toBeSaved);
        return toBeSaved;
    }

    @Transactional
//    @CacheEvict(value="accountCache",key="#account.getName()")// 清空accountCache 缓存
    private void saveRoleUser(Long userId, Integer userType) {
        List<Role> roleList = null;
        if (userType == 1) {// 1-医生 2-病人 3-家属 其他待加
        	roleList = roleRepository.findRole(RoleConstants.DOCTOR);
		} if (userType == 2) {// 1-医生 2-病人 3-家属 其他待加
        	roleList = roleRepository.findRole(RoleConstants.PATIENT);
		} else if(userType == 3) {
        	roleList = roleRepository.findRole(RoleConstants.RELATIVES);
		}
		List<UserRole> userRoleList = new ArrayList<UserRole>();
		for (Role role : roleList) {
			UserRole userRole = new UserRole();
			userRole.setUserId(userId);
			userRole.setRoleId(role.getId());
			userRole.setCreateBy(userId);
			userRole.setCreateTs(new Date());
			userRoleList.add(userRole);
		}
		userRoleRepository.save(userRoleList);
    }

    
    
    @Override
    @Transactional
    public Boolean checkIsComplete(Long userId) {
        User targetUser = null;
        // 查当前用户
        if (userId < 0) {
            targetUser = SecurityContext.getInstance().getCurrentUser();
        } else {
            targetUser = userRepository.findOne(userId);
            if (targetUser == null) {
                return Boolean.FALSE;
            }
        }

        UserInfo userInfo = userInfoService.findByUserId(targetUser.getId());
        if (userInfo == null) {
            userInfo = new UserInfo();
            userInfo.setCreateBy(1L);
            userInfo.setCreateTs(new Date());
            userInfo.setUserId(targetUser.getId());
            userInfoService.save(userInfo);
        }

        if (userInfo.getInformationComplete() == null || userInfo.getInformationComplete() <= 0) {
            // 未补充完全
            return Boolean.FALSE;
        } else if (userInfo.getInformationComplete() != null && userInfo.getInformationComplete() >= 0) {
            // 补充完全
            return Boolean.FALSE;
        } else {
            return Boolean.TRUE;
        }
    }

    @Override
    @Transactional
    public ResultDto completeUser(UserInfoDto userInfoDto) {
        Long userId = userInfoDto.getUserId();
        User targetUser = null;
        if (userId == null) {
            targetUser = SecurityContext.getInstance().getCurrentUser();
        } else {
            targetUser = userRepository.findOne(userId);
        }
        if (targetUser == null) {
            return ResultDtoFactory.toNack("用户不存在");
        }
        if (StringUtils.isNotBlank(userInfoDto.getName())) {
            targetUser.setName(userInfoDto.getName());
            userService.saveUser(targetUser);
        }

        // 补齐修改资料用户信息
        UserInfo infoDomain = userInfoRepository.findByUserId(targetUser.getId());
        if (infoDomain == null) {
            infoDomain = new UserInfo();
            infoDomain.setCreateBy(targetUser.getId());
            infoDomain.setCreateTs(new Date());
            infoDomain.setUserId(targetUser.getId());
        } else {
            infoDomain.setNickName(userInfoDto.getNickName());
            infoDomain.setUserExerciseTime(userInfoDto.getUserExerciseTime());
            infoDomain.setBornDate(DateUtils.getFormatDateByString(userInfoDto.getBornDate(), DateUtils.STRING_PATTERN_SHORT));
            infoDomain.setAvatarUrl(userInfoDto.getAvatarUrl());
            infoDomain.setFamillyMobile(userInfoDto.getFamillyMobile());
            infoDomain.setFamillyName(userInfoDto.getFamillyName());
            infoDomain.setInviteCode(userInfoDto.getInviteCode());
            infoDomain.setNickName(userInfoDto.getNickName());
            infoDomain.setUserExerciseTime(userInfoDto.getUserExerciseTime());
            infoDomain.setUpdateTs(new Date());
            infoDomain.setUpdateBy(targetUser.getId());
        }
        
        userInfoService.save(infoDomain);

        return ResultDtoFactory.toAck("更新成功");
    }

    /**
     * 根据用户名密码获取 未加密前的密码字符串
     * 
     * @param pass
     * @param username
     * @return
     */
    private String getPassword(String pass, String username) {
        return pass + Integer.toString(username.substring(0, 4).hashCode());
    }

    @Override
    public ResultDto checkOldPass(String oldPass) {
        User user = SecurityContext.getInstance().getCurrentUser();

        String oldPassInstored = user.getPassword();
        String pwd = passwordService.encryptPassword(getPassword(oldPass, user.getUsername()));

        if (oldPassInstored.equals(pwd)) {
            return ResultDtoFactory.toAckNomessage("success");
        } else {
            return ResultDtoFactory.toAckNomessage("fail");
        }
    }

    @Override
    public ResultDto changePwdAndRedirect(String oldPass, String nowPass) {
        User currentUser = SecurityContext.getInstance().getCurrentUser();

        String pwd = passwordService.encryptPassword(getPassword(oldPass, currentUser.getUsername()));
        String oldPassInstored = currentUser.getPassword();

        if (!oldPassInstored.equals(pwd)) {
            return ResultDtoFactory.toNack("原密码错误！");
        }

        String newPassword = passwordService.encryptPassword(getPassword(nowPass, currentUser.getUsername()));
        currentUser.setPassword(newPassword);

        userRepository.save(currentUser);
        
        return ResultDtoFactory.toRedirect(WebUtil.getFullUrlBasedOn("/web/home"), "修改成功");
    }

}
